﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using Xpedite.Localization;
using Xpedite.Resources;
using Xpedite.Resources.Definitions;
using Xpedite.WebAbstraction;

/* Copyright (c) 2010 CBaxter
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE. 
 */

namespace Xpedite.Extensions
{
  internal static class HtmlTextWriterExtensions
  {
    public static void RenderCssStyleSheetLink(this HtmlTextWriter writer, IResourceUrl url)
    {
      writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
      writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
      writer.AddAttribute(HtmlTextWriterAttribute.Href, url.VirtualPath);
      writer.RenderBeginTag(HtmlTextWriterTag.Link);
      writer.RenderEndTag();
    }

    public static void RenderJavaScriptSourceScript(this HtmlTextWriter writer, IResourceUrl url)
    {
      writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
      writer.AddAttribute(HtmlTextWriterAttribute.Src, url.VirtualPath);
      writer.RenderBeginTag(HtmlTextWriterTag.Script);
      writer.RenderEndTag();
    }

    public static void RenderCssSprite(this HtmlTextWriter writer, IResourceDefinition spriteDefinition, String imageName, String altText, String id)
    {
      String resourceType = spriteDefinition.ResourceType.ToString().ToLowerInvariant();
      IResourceContainer resourceContainer = spriteDefinition.GetResource(imageName);
      ImageResource resource = resourceContainer.Resource as ImageResource;
      String spriteName = spriteDefinition.ReferenceName;

      if (resource == null)
        throw new XpediteException(String.Format(ExceptionMessages.ImageResourceExpected, imageName, spriteName));

      if (!String.IsNullOrEmpty(id))
        writer.AddAttribute(HtmlTextWriterAttribute.Id, id);

      if (!String.IsNullOrEmpty(altText))
      {
        writer.AddAttribute(HtmlTextWriterAttribute.Alt, altText);
        writer.AddAttribute(HtmlTextWriterAttribute.Title, altText);
      }

      writer.AddAttribute(HtmlTextWriterAttribute.Class, String.Format("xpedite-{0}-{1} {2}", resourceType, spriteName, imageName));
      writer.AddAttribute(HtmlTextWriterAttribute.Src, WebHost.ApplicationVirtualPath + "/xpedite.sprite.xcr"); 
      writer.AddAttribute(HtmlTextWriterAttribute.Width, resource.Size.Width.ToString());
      writer.AddAttribute(HtmlTextWriterAttribute.Height, resource.Size.Height.ToString());

      writer.RenderBeginTag(HtmlTextWriterTag.Img);
      writer.RenderEndTag();
    }

    public static void RenderCompositeDefinitions(this HtmlTextWriter writer, IEnumerable<IResourceDefinition> definitions)
    {
      foreach (var definition in definitions)
        writer.RenderCompositeDefinition(definition);
    }

    public static void RenderCompositeDefinition(this HtmlTextWriter writer, IResourceDefinition definition)
    {
      definition.EmitResource(writer);
    }

    public static void RenderDebuggableDefinitions(this HtmlTextWriter writer, IEnumerable<IResourceDefinition> definitions)
    {
      foreach (var definition in definitions)
        writer.RenderDebuggableDefinition(definition);
    }

    public static void RenderDebuggableDefinition(this HtmlTextWriter writer, IResourceDefinition definition)
    {
      if (definition.ResourceType == ResourceType.Css || definition.ResourceType == ResourceType.JavaScript)
      {
        Action<IResourceUrl> renderer = GetResourceTypeRenderer(definition.ResourceType, writer);

        foreach (var resource in definition.Resources)
          renderer.Invoke(resource.ResourceUrl);
      }
      else
      {
        writer.RenderCompositeDefinition(definition);
      }
    }

    private static Action<IResourceUrl> GetResourceTypeRenderer(ResourceType type, HtmlTextWriter writer)
    {
      switch (type)
      {
        case ResourceType.JavaScript: return writer.RenderJavaScriptSourceScript;
        case ResourceType.Css: return writer.RenderCssStyleSheetLink;
        default: return url => { };
      }
    }
  }
}
